package com.rockcent.mall.controller;

import com.rockcent.common.common.JsonResult;
import com.rockcent.common.common.PageResult;
import com.rockcent.common.common.RestDoing;
import com.rockcent.common.controller.BaseController;
import com.rockcent.common.domain.enumclass.Whether;
import com.rockcent.common.utils.DateFormatUtils;
import com.rockcent.common.utils.DateUtils;
import com.rockcent.mall.Prop;
import com.rockcent.mall.Routes;
import com.rockcent.mall.helper.ChannelHelper;
import com.rockcent.mall.lib.domain.*;
import com.rockcent.mall.lib.domain.enumclass.ChannelClientType;
import com.rockcent.mall.lib.domain.enumclass.ChannelStatus;
import com.rockcent.mall.lib.domain.enumclass.StatististicsType;
import com.rockcent.mall.lib.domain.enumclass.UploadFileBusinessType;
import com.rockcent.mall.lib.dto.*;
import com.rockcent.mall.lib.helper.BaseUserHelper;
import com.rockcent.mall.lib.helper.QRCodeHelper;
import com.rockcent.mall.lib.repository.*;
import org.apache.commons.lang3.EnumUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.util.*;

/**
 * Created by zhangjh on 2016/10/24.
 */
@RestController
public class MerchantChannelController extends BaseController {


    private final Logger log = LoggerFactory.getLogger(MerchantChannelController.class);

    @Autowired
    private BaseUserHelper userHelper;

    @Autowired
    private QRCodeHelper qrCodeHelper;

    @Autowired
    private Prop prop;

    @Autowired
    private MerchantChannelRepository merchantChannelRepository;

    @Autowired
    private MerchantChannelStatisticsRepository merchantChannelStatisticsRepository;

    @Autowired
    private MerchantRepository merchantRepository;

    @Autowired
    private MallRepository mallRepository;

    @Autowired
    private ChannelCategoryRepository channelCategoryRepository;

    @Autowired
    private ChannelTypeRepository channelTypeRepository;

    @Autowired
    private ChannelProductRepository channelProductRepository;

    @Autowired
    private MerchantProductRepository merchantProductRepository;

    @Autowired
    private ChannelStatisticsRepository channelStatisticsRepository;

    @Autowired
    private ChannelHelper channelHelper;

    @Autowired
    private MerchantOrderRepository merchantOrderRepository;

    @Autowired
    private MiniAppConfigRepository miniAppConfigRepository;


    /**
     * @api {get} /merchant/channel/page  B端 渠道管理 渠道信息 分页
     * @apiGroup merchant_channel
     * @apiVersion 1.0.0
     * @apiHeader {String} userToken 用户token
     * @apiHeader {String} domain    请求域名
     * @apiParam {String} name       渠道名字
     * @apiParam {String} channelStatus <coe>必须为 USING("使用中")或 STOP("停用")</coe>渠道状态
     * @apiParam {Long} channelTypeId <coe>不传代表全部渠道</coe> 渠道类型ID
     * @apiParam {String} channelClientType 客户端渠道类型 <coe>不传代表全部</coe> WXH5("微信H5"),WXAPP("微信小程序")
     * @apiSuccessExample {json} Success-Response:
     *{
     *"code": "1",
     *"desc": "成功",
     *"data": {
     *   "data": [
     *      {
     *         "id": 73,
     *         "name": "默认自有渠道1",
     *         "channelTypeId": 14,
     *         "number": "001",
     *         "channelStatus": "USING",
     *         "sellCount": 0,
     *         "verifiedCount": 0,
     *         "productCount":10,
     *         "systemDefault": false
     *      }
     *       ...
     *       ],
     *      "totalCount": 12,
     *      "totalPage": 2,
     *      "pageNo": 0,
     *      "pageSize": 10,
     *      "url": "/merchant/channel/page",
     *      "prevUrl": "/merchant/channel/page?pageNo=0&pageSize=10",
     *      "nextUrl": "/merchant/channel/page?pageNo=1&pageSize=10"
     * }
     * }
     */
    @RequestMapping(value = Routes.MERCHANT_CHANNEL_PAGE, method = RequestMethod.GET)
    public JsonResult listChannels(ChannelDto channelDto, HttpServletRequest request) {
        UserInfoDto userInfoDto = userHelper.getSession(request);
        RestDoing doing = jsonResult -> {
            PageResult pageResult = getPage(channelDto.getPageNo(), channelDto.getPageSize());
            if (StringUtils.isNotBlank(channelDto.getChannelStatus()) && !EnumUtils.isValidEnum(ChannelStatus.class, channelDto.getChannelStatus())) {
                jsonResult.remind("channelStatus 必须为 USING(\"使用中\"),STOP(\"停用\")",log);
                return;
            }
            //如果查询channelTypeId为一级 则将下级的channelTypeId加入列表
            List<Long> channelTypeIds = new ArrayList<>();
            if (channelDto.getChannelTypeId() != null && channelDto.getChannelTypeId().longValue() > 0) {
                ChannelType channelType = channelTypeRepository.findOne(channelDto.getChannelTypeId());
                if (channelType == null) {
                    jsonResult.remind("渠道类型ID不存在",log);
                    return;
                }
                if (channelType.getParentId() == null) {
                    List<ChannelType> channelTypes = channelTypeRepository.findByParentIdAndIsDelete(channelDto.getChannelTypeId(), Whether.NO);
                    if (channelTypes != null && channelTypes.size() > 0) {
                        for (ChannelType ch : channelTypes) {
                            channelTypeIds.add(ch.getId());
                        }
                    }
                } else {
                    channelTypeIds.add(channelDto.getChannelTypeId());
                }
            }
            PageResult<ChannelDto> result = merchantChannelRepository.findByMerchantId(userInfoDto.merchant.getId(), userInfoDto.mall.getId(), channelDto.getChannelStatus(), channelTypeIds, channelDto.getName(), channelDto.getChannelClientType(), pageResult);
            result.data.forEach(channel -> {
                Long channelId = channel.getId();
                ChannelStatistics statistics = channelStatisticsRepository.getByMerchantIdAndMallIdAndChannelId(userInfoDto.merchant.getId(), userInfoDto.mall.getId(), channelId);

                if (statistics != null) {
                    //核销数
                    channel.setVerifiedCount(statistics.getVerifyCount() == null ? 0 : statistics.getVerifyCount());
                    //售出数
                    channel.setSaleCount(statistics.getSaleCount() == null ? 0 : statistics.getSaleCount());
                }
                Long productCount = channelProductRepository.productCountByChannelId(channelId);
                channel.setProductCount(productCount == null ? 0 : productCount);
            });

            result.setUrl(Routes.MERCHANT_CHANNEL_PAGE);
            jsonResult.data = result;
        };

        return doing.go(request, log);
    }

    /**
     * @api {post} /merchant/channel/save  B 端 渠道管理 渠道信息 保存
     * @apiGroup merchant_channel
     * @apiVersion 1.0.0
     * @apiHeader {String} userToken 用户token
     * @apiHeader {String} domain    请求域名
     * @apiParam {Long} id           渠道ID
     * @apiParam {String} name       渠道名字
     * @apiParam {String} intro      渠道简介
     * @apiParam {String} channelStatus<code>USING("使用中"), STOP("停用")</code>  渠道状态
     * @apiParam {String} iconUrl      渠道图标Url
     * @apiParam {String} flowEstimation  流量估计
     * @apiParam {Long} channelTypeId 渠道类型ID
     * @apiParam {List} categoryIds 渠道产品分类列表ID
     * @apiParam {String} detail 渠道描述
     * @apiParam {String} activityName 活动名称
     * @apiParam {String} appFlag 小程序标志 (是:YES,否:NO)
     * @apiParam {String} appDefault 小程序默认渠道标志（供线上使用） (是:YES,否:NO)
     * @apiParam {String} channelClientType 客户端渠道类型 WXH5("微信H5"),WXAPP("微信小程序")
     * @apiSuccessExample {json} Success-Response:
     * {
     * "code": "1",
     * "desc": "成功",
     * }
     */
    @Transactional
    @RequestMapping(value = Routes.MERCHANT_CHANNEL_SAVE, method = RequestMethod.POST)
    public JsonResult saveChannel(@RequestBody ChannelDto channelDto, HttpServletRequest request) {
        UserInfoDto userInfoDto = userHelper.getSession(request);
        RestDoing doing = jsonResult -> {
            if (StringUtils.isBlank(channelDto.getName())) {
                jsonResult.remind("name 不能为空",log);
                return;
            }

            if (StringUtils.isBlank(channelDto.getFlowEstimation())) {
                jsonResult.remind("flowEstimation 不能为空",log);
                return;
            }
            if (channelDto.getIconUrl() == null) {
                jsonResult.remind("iconUrl 不能为空",log);
                return;
            }
            if (channelDto.getChannelTypeId() == null) {
                jsonResult.remind("channelTypeId 不能为空",log);
                return;
            }
            if (channelDto.getCategoryIds() == null || channelDto.getCategoryIds().isEmpty()) {
                jsonResult.remind("categoryIds 不能为空",log);
                return;
            }

            Channel channel = new Channel();
            channel.setSalesCode(channelDto.getNumber() == null ? channelHelper.genSalesCode() : channelDto.getNumber());
            channel.setName(channelDto.getName());
            //活动名称
            if(StringUtils.isNotEmpty(channelDto.getActivityName())) {
                channel.setActivityName(channelDto.getActivityName());
            }
            //小程序标志
            if(StringUtils.isNotEmpty(channelDto.getAppFlag())) {
                channel.setAppFlag(Whether.valueOf(channelDto.getAppFlag()));
                //小程序默认标志
                if(StringUtils.isNotEmpty(channelDto.getAppDefault())) {
                    channel.setAppDefault(Whether.valueOf(channelDto.getAppDefault()));
                }
            }
            if(StringUtils.isNotEmpty(channelDto.getChannelClientType())) {
                if (!EnumUtils.isValidEnum(ChannelClientType.class, channelDto.getChannelClientType())) {
                    jsonResult.remind("ChannelClientType 必须为 WXH5(\"微信H5\"),WXAPP(\"微信小程序\")",log);
                    return;
                }
                channel.setChannelClientType(ChannelClientType.valueOf(channelDto.getChannelClientType()));
            }
            channel.setChannelStatus(ChannelStatus.valueOf(channelDto.getChannelStatus()));
            channel.setChannelTypeId(channelDto.getChannelTypeId());
            channel.setDetail(channelDto.getDetail());
            channel.setIntro(channelDto.getIntro());
            channel.setIconUrl(channelDto.getIconUrl());
            channel.setFlowEstimation(channelDto.getFlowEstimation());
            channel.setMerchantId(userInfoDto.merchant.getId());
            channel.setMallId(userInfoDto.mall.getId());
            channel.setSystemDefault(channelDto.getSystemDefault() == null ? false : channelDto.getSystemDefault());
            channel = merchantChannelRepository.saveAndFlush(channel);
            Long channelId = channel.getId();
            channelDto.getCategoryIds().forEach(productCategoryId -> {
                channelCategoryRepository.save(channelId, productCategoryId);
            });
            MerchantChannelStatistics channelStatistics = new MerchantChannelStatistics();
            channelStatistics.setChannelId(channelId);
            channelStatistics.setMallId(userInfoDto.mall.getId());
            channelStatistics.setMerchantId(userInfoDto.merchant.getId());
            channelStatistics.setClickCount(0);
            channelStatistics.setSaleCount(0);
            channelStatistics.setShareCount(0);
            channelStatistics.setVerifyCount(0);
            channelStatistics.setViewCount(0);
            merchantChannelStatisticsRepository.save(channelStatistics);

        };
        return doing.go(request, log);
    }

    /**
     * @api {get} /merchant/channel/info  B端 渠道管理 渠道信息 获取
     * @apiGroup merchant_channel
     * @apiVersion 1.0.0
     * @apiHeader {String} userToken 用户token
     * @apiHeader {String} domain    请求域名
     * @apiParam {Long} id           渠道ID
     * @apiSuccessExample {json} Success-Response:
     * {
     * "code": "1",
     * "desc": "成功",
     * "data":
     *      {
     *         "id": 73,
     *         "dateCreated": "2016-07-28 16:59:19",
     *         "lastUpdated": "2016-10-24 14:40:52",
     *         "version": 0,
     *         "name": "默认自有渠道1",
     *         "channelTypeId": 14,
     *         "flowEstimation": "未知",
     *         "intro": "系统创建默认自有渠道",
     *         "detail": "系统创建默认自有渠道",
     *         "number": "001",
     *         "channelStatus": "USING",
     *         "merchantId": 1,
     *         "mallId": 1,
     *         "systemDefault": true
     *      }
     * }
     */
    @RequestMapping(value = Routes.MERCHANT_CHANNEL_INFO, method = RequestMethod.GET)
    public JsonResult getChannelInfo(ChannelDto channelDto, HttpServletRequest request) {
        UserInfoDto userInfoDto = userHelper.getSession(request);
        RestDoing doing = jsonResult -> {
            if (channelDto.getId() == null) {
                jsonResult.remind("ID 不能为空", log);
                return;
            }
            ChannelDto channel = this.merchantChannelRepository.getChannelById(channelDto.getId(), userInfoDto.merchant.getId(), userInfoDto.mall.getId(), Whether.NO);
            if (channel == null) {
                jsonResult.remind("加载信息出错", log);
                return;
            }
            ChannelType channelType = this.channelTypeRepository.findOne(channel.getChannelTypeId());
            Long channelTypeParentId = channelType.getParentId();
            List<Map> categorys = this.channelCategoryRepository.getCategoryByChannelId(channel.getId());
            channel.setChannelTypeParentId(channelTypeParentId);
            categorys.forEach(map -> {
                channel.getCategoryIds().add(new Long(map.get("categoryId").toString()));
            });
            jsonResult.data = channel;

        };
        return doing.go(request, log);
    }

    /**
     * @api {post} /merchant/channel/update  B端 渠道管理渠道信息 更新
     * @apiGroup merchant_channel
     * @apiVersion 1.0.0
     * @apiHeader {String} userToken 用户token
     * @apiHeader {String} domain    请求域名
     * @apiParam {Long} id           渠道ID
     * @apiParam {String} name       渠道名字
     * @apiParam {String} intro      渠道简介
     * @apiParam {String} channelStatus<code>USING("使用中"), STOP("停用")</code>  渠道状态
     * @apiParam {String} iconUrl      渠道图标Url
     * @apiParam {String} flowEstimation  流量估计
     * @apiParam {Long} channelTypeId 渠道类型ID
     * @apiParam {List} categoryIds 渠道产品分类列表ID
     * @apiParam {String} detail 渠道描述
     * @apiParam {String} activityName 活动名称
     * @apiParam {String} appFlag 小程序标志 (是:YES,否:NO)
     * @apiParam {String} appDefault 小程序默认渠道标志（供线上使用） (是:YES,否:NO)
     * @apiParam {String} channelClientType 客户端渠道类型 WXH5("微信H5"),WXAPP("微信小程序")
     *
     * @apiSuccessExample {json} Success-Response:
     * {
     * "code": "1",
     * "desc": "成功",
     * }
     */
    @Transactional
    @RequestMapping(value = Routes.MERCHANT_CHANNEL_UPDATE, method = RequestMethod.POST)
    public JsonResult updateChannel(@RequestBody ChannelDto channelDto, HttpServletRequest request) {
        UserInfoDto userInfoDto = userHelper.getSession(request);
        RestDoing doing = jsonResult -> {
            if (channelDto.getId() == null) {
                jsonResult.remind("ID 不能为空", log);
                return;
            }
            if (StringUtils.isBlank(channelDto.getName())) {
                jsonResult.remind("name 不能为空",log);
                return;
            }
            if (StringUtils.isBlank(channelDto.getChannelStatus())) {
                jsonResult.remind("channelStatus 不能为空",log);
                return;
            } else if (!EnumUtils.isValidEnum(ChannelStatus.class, channelDto.getChannelStatus())) {
                jsonResult.remind("channelStatus 必须为 USING(\"使用中\"),STOP(\"停用\") DELETE(\"删除\")",log);
                return;
            }
            if (StringUtils.isBlank(channelDto.getFlowEstimation())) {
                jsonResult.remind("flowEstimation 不能为空",log);
                return;
            }
            if (channelDto.getIconUrl() == null) {
                jsonResult.remind("iconUrl 不能为空",log);
                return;
            }
            if (channelDto.getChannelTypeId() == null) {
                jsonResult.remind("channelTypeId 不能为空",log);
                return;
            }

            Channel channel = this.merchantChannelRepository.getChannelByIdAndMerchantIdAndMallIdAndIsDelete(channelDto.getId(), userInfoDto.merchant.getId(), userInfoDto.mall.getId(), Whether.NO);
            if (StringUtils.isNotBlank(channelDto.getName())) {
                channel.setName(channelDto.getName());
            }
            if (StringUtils.isNotBlank(channelDto.getChannelStatus())) {
                channel.setChannelStatus(ChannelStatus.valueOf(channelDto.getChannelStatus()));
            }
            if (channelDto.getChannelTypeId() != null) {
                channel.setChannelTypeId(channelDto.getChannelTypeId());
            }
            if (StringUtils.isNotBlank(channelDto.getDetail())) {
                channel.setDetail(channelDto.getDetail());
            }
            if (StringUtils.isNotBlank(channelDto.getIntro())) {
                channel.setIntro(channelDto.getIntro());
            }
            if (StringUtils.isNotBlank(channelDto.getIconUrl())) {
                channel.setIconUrl(channelDto.getIconUrl());
            }
            if (StringUtils.isNotBlank(channelDto.getFlowEstimation())) {
                channel.setFlowEstimation(channelDto.getFlowEstimation());
            }
            if (channelDto.getSystemDefault() != null) {
                channel.setSystemDefault(channelDto.getSystemDefault());
            }
            //活动名称
            if(StringUtils.isNotEmpty(channelDto.getActivityName())) {
                channel.setActivityName(channelDto.getActivityName());
            }
            //小程序标志
            if(StringUtils.isNotEmpty(channelDto.getAppFlag())) {
                channel.setAppFlag(Whether.valueOf(channelDto.getAppFlag()));
                //小程序默认标志
                if(StringUtils.isNotEmpty(channelDto.getAppDefault())) {
                    channel.setAppDefault(Whether.valueOf(channelDto.getAppDefault()));
                }
            }
            if(StringUtils.isNotEmpty(channelDto.getChannelClientType())) {
                if (!EnumUtils.isValidEnum(ChannelClientType.class, channelDto.getChannelClientType())) {
                    jsonResult.remind("ChannelClientType 必须为 WXH5(\"微信H5\"),WXAPP(\"微信小程序\")",log);
                    return;
                }
                channel.setChannelClientType(ChannelClientType.valueOf(channelDto.getChannelClientType()));
            }
            channel = merchantChannelRepository.saveAndFlush(channel);
            Long channelId = channel.getId();
            channelCategoryRepository.delete(channelId);
            if (channelDto.getCategoryIds() != null) {
                channelDto.getCategoryIds().forEach(productCategoryId -> {
                    channelCategoryRepository.save(channelId, productCategoryId);
                });
            }


        };
        return doing.go(request, log);
    }

    /**
     * @api {put} /merchant/channel/delete B端 渠道管理 渠道 删除
     * @apiGroup merchant_channel
     * @apiVersion 1.0.0
     * @apiHeader {String} userToken 用户token
     * @apiHeader {String} domain    请求域名
     * @apiParam {List} ids           渠道ID集合
     * @apiSuccessExample {json} Success-Response:
     * {
     * "code": "1",
     * "desc": "成功",
     * }
     */
    @Transactional
    @RequestMapping(value = Routes.MERCHANT_CHANNEL_DELETE, method = RequestMethod.PUT)
    public JsonResult deleteChannel(@RequestBody ChannelDto channelDto, HttpServletRequest request) {

        UserInfoDto userInfoDto = userHelper.getSession(request);
        RestDoing doing = jsonResult -> {
            if (channelDto.getIds() == null || channelDto.getIds().isEmpty()) {
                jsonResult.remind("ids 不能为空", log);
                return;
            }
            channelDto.getIds().forEach(channelId -> {
                Channel channel = this.merchantChannelRepository.getChannelByIdAndMerchantIdAndMallIdAndIsDelete(channelId, userInfoDto.merchant.getId(), userInfoDto.mall.getId(), Whether.NO);
                if (channel == null) {
                    jsonResult.remind("渠道信息加载失败", log);
                    return;
                }
                channelCategoryRepository.delete(channelId);
                Long count = channelProductRepository.countByChannelId(channelId);
                if (count != null && count > 0) {
                    channelProductRepository.deleteByChannelId(channelId);
                }
                channel.setIsDelete(Whether.YES);
                channel.setChannelStatus(ChannelStatus.DELETE);
                this.merchantChannelRepository.save(channel);
                MerchantChannelStatistics statistics = merchantChannelStatisticsRepository.getByChannelId(channelId);
                statistics.setIsDelete(Whether.YES);
                merchantChannelStatisticsRepository.save(statistics);
            });
        };
        return doing.go(request, log);

    }

    /**
     *
     * @api {put} /merchant/channel/status/update  B端 渠道管理 启用|停用
     * @apiGroup merchant_channel
     * @apiVersion 1.0.0
     * @apiHeader {String} userToken 用户token
     * @apiHeader {String} domain    请求域名
     * @apiParam {Long} id <code>必传参数</code>    渠道ID
     * @apiParam {String} channelStatus   <code>必传参数 USING("使用中"),STOP("停用")</code> 渠道状态
     * @apiSuccessExample {json} Success-Response:
     * {
     * "code": "1",
     * "desc": "成功",
     * }
     */
    @RequestMapping(value = Routes.MERCHANT_CHANNEL_STATUS_UPATE, method = RequestMethod.PUT)
    public JsonResult updateChannelStatus(@RequestBody ChannelDto channelDto, HttpServletRequest request) {
        UserInfoDto userInfoDto = userHelper.getSession(request);

        RestDoing doing = jsonResult -> {
            if (channelDto.getId() == null) {
                jsonResult.remind("id 不能为空", log);
                return;
            }
            if (StringUtils.isBlank(channelDto.getChannelStatus())) {
                jsonResult.remind("channelStatus 不能为空",log);
                return;
            }
            if (!EnumUtils.isValidEnum(ChannelStatus.class, channelDto.getChannelStatus())) {
                jsonResult.remind("channelStatus 必须为 USING(\"使用中\"),STOP(\"停用\")",log);
                return;
            }
            Channel channel = this.merchantChannelRepository.getChannelByIdAndMerchantIdAndMallIdAndIsDelete(channelDto.getId(), userInfoDto.merchant.getId(), userInfoDto.mall.getId(), Whether.NO);
            channel.setChannelStatus(ChannelStatus.valueOf(channelDto.getChannelStatus()));
            this.merchantChannelRepository.save(channel);

        };
        return doing.go(request, log);
    }

    /**
     *
     * @api {get} /merchant/channel/selected/product/page B端 渠道管理  已上架 产品列表 分页
     * @apiGroup merchant_channel
     * @apiVersion 1.0.0
     * @apiHeader {String} userToken 用户token
     * @apiHeader {String} domain    请求域名
     * @apiParam {Long} channelId   <code>必传参数</code>   渠道ID
     * @apiParam {String} scope   <code>self 自营产品   share 分销产品   不传代表全部</code> 产品类型
     * @apiParam {String} productName   产品名称/编号
     *
     * @apiSuccess {Long} id id
     * @apiSuccess {Long} productId 产品ID
     * @apiSuccess {String} productName 产品名称
     * @apiSuccess {String} barCode 产品编码
     * @apiSuccess {String} promoteUrl 产品推广URL
     * @apiSuccess {BigDecimal} sellPrice 产品售价
     * @apiSuccess {Long} quantity 产品库存
     * @apiSuccess {Long} viewCount 产品浏览数
     * @apiSuccess {Long} verifyCount 产品核销数
     * @apiSuccess {String=SELLING("在售"),SUPPLIER_CANCEL_SOLDOUT("分销市场 供应商取消供货 已下架"),DISTRIBUTOR_CANCEL_SOLDOUT("分销市场 分销商取消代销 已下架"),SUPPLIER_COOPERATION_STOP("分销市场 供应商终止合作"),DISTRIBUTOR_COOPERATION_STOP("分销市场 分销商终止合作"),SOLDOUT("已下架"),EXPIRED("已过期"),DELETED("已删除"),WAIT_AUDIT("待审核"),AUDIT_FAIL("审核不通过"),DRAFT("草稿"),ILLEGAL ("违规下架")} status 产品状态
     * @apiSuccessExample {json} Success-Response:
     *  "code": "1",
     *  "desc": "成功",
     *  "data": [
     *      {
     *          "id": 14,
     *          "productId": 72,
     *          "productName": "[15店通用] 四川香天下火锅",
     *          "barCode": "11111111",
     *          "promoteUrl": "http://uploads.test.com/uploads/111.jsp",
     *          "sellPrice": 0.01,
     *          "quantity": 97,
     *          "dateDisabled": "2017-06-06 00:00:00",
     *          "viewCount": 1074,
     *          "saleCount": 0,
     *          "verifyCount": 0,
     *          "status": "SELLING",
     *          "marketId":215
     *      }
     *      ...
     *      ]
     *       ],
     *      "totalCount": 64,
     *      "totalPage": 7,
     *      "pageNo": 0,
     *      "pageSize": 10,
     *      "url": "/merchant/channel/selected/product/page",
     *      "prevUrl": "/merchant/channel/selected/product/page?pageNo=0&pageSize=10",
     *      "nextUrl": "/merchant/channel/selected/product/page?pageNo=1&pageSize=10"
     *  }
     */
    @RequestMapping(value = Routes.MERCHANT_CHANNEL_SELECTED_PRODUCTS_PAGE, method = RequestMethod.GET)
    public JsonResult channelProductList(HttpServletRequest request, ChannelProductDto channelProductDto) {
        UserInfoDto userInfoDto = userHelper.getSession(request);
        RestDoing doing = jsonResult -> {
            if (channelProductDto.getChannelId() == null) {
                jsonResult.remind("channelId 不能为空", log);
                return;
            }
            PageResult pageResult = this.getPage(channelProductDto.getPageNo(), channelProductDto.getPageSize());
            PageResult<ChannelProductDto> result = channelProductRepository.findByChannelIdAndScope(channelProductDto.getChannelId(), channelProductDto.getProductName(), channelProductDto.getScope(), pageResult);
            result.data.forEach(product -> {
                Long saleCount = merchantOrderRepository.countProductSaleByChannelId(product.getId(), userInfoDto.merchant.getId(), userInfoDto.mall.getId(), channelProductDto.getChannelId());
                Long verifyCount = merchantOrderRepository.countProductVerifyByChannelId(product.getId(), userInfoDto.merchant.getId(), userInfoDto.mall.getId(), channelProductDto.getChannelId());
                product.setSaleCount(saleCount == null ? 0 : saleCount.intValue());
                product.setVerifyCount(verifyCount == null ? 0 : verifyCount.intValue());
            });
            result.setUrl(Routes.MERCHANT_CHANNEL_SELECTED_PRODUCTS_PAGE);
            jsonResult.data = result;
        };
        return doing.go(request, log);
    }


    /**
     *
     * @api {get} /merchant/channel/product/page B端 渠道管理 未上架 产品列表 分页
     * @apiGroup merchant_channel
     * @apiVersion 1.0.0
     * @apiHeader {String} userToken 用户token
     * @apiHeader {String} domain    请求域名
     * @apiParam {Long} channelId <code>必传参数</code>   渠道ID
     * @apiParam {String} scope   <cod>取值：self | share </cod> 自营/分销
     * @apiSuccessExample {json} Success-Response:
     * {
     *  "code": "1",
     *  "desc": "成功",
     *  "data": [
     *      {
     *        "id": 95,
     *        "name": "跨平台商品",
     *        "sellPrice": 100,
     *        "quantity": 1000,
     *        "dateDisabled": "2016-10-26 18:54:22",
     *        "barcode": "00001",
     *        "promoteUrl": "http://123.jsp"
     *      }
     *      ...
     *      ]，
     *      "url": "/merchant/channel/product/page",
     *      "prevUrl": "/merchant/channel/product/page?pageNo=0&pageSize=10",
     *      "nextUrl": "/merchant/channel/product/page?pageNo=-1&pageSize=10"
     *  }
     **/
    @RequestMapping(value = Routes.MERCHANT_CHANNEL_PRODUCTS_PAGE, method = RequestMethod.GET)
    public JsonResult listMerchantProduct(HttpServletRequest request, ChannelProductDto channelProductDto) {
        UserInfoDto userInfoDto = userHelper.getSession(request);
        RestDoing doing = jsonResult -> {
            if (channelProductDto.getChannelId() == null) {
                jsonResult.remind("channelId 不能为空", log);
                return;
            }
            PageResult pageResult = this.getPage(channelProductDto.getPageNo(), channelProductDto.getPageSize());
            PageResult<ProductDto> result = channelProductRepository.listProductByMerchantIdAndMallIdAndChannelId(userInfoDto.merchant.getId(), userInfoDto.mall.getId(), channelProductDto.getChannelId(), channelProductDto.getScope(), pageResult);
//            result.forEach(product -> {
//                Long saleCount= merchantOrderRepository.countProductSaleByChannelId(product.getId(),userInfoDto.merchant.getId(),userInfoDto.mall.getId(),channelProductDto.getChannelId());
//                Long verifyCount= merchantOrderRepository.countProductVerifyByChannelId(product.getId(),userInfoDto.merchant.getId(),userInfoDto.mall.getId(),channelProductDto.getChannelId());
//                product.setSaleCount(saleCount==null?"0":saleCount.toString());
//                product.setVerifyCount(verifyCount==null?"0":verifyCount.toString());
//            });

            result.setUrl(Routes.MERCHANT_CHANNEL_PRODUCTS_PAGE);
            jsonResult.data = result;
        };
        return doing.go(request, log);
    }


    /**
     *
     * @api {post} /merchant/channel/product/update B端 渠道管理 产品添加
     * @apiGroup merchant_channel
     * @apiVersion 1.0.0
     * @apiHeader {String} userToken 用户token
     * @apiHeader {String} domain    请求域名
     * @apiParam {Long} id <code>必传参数</code>   渠道ID
     * @apiParam {List} productIds <code>必传参数</code>   选定产品ID集合
     * @apiSuccessExample {json} Success-Response:
     * {
     *  "code": "1",
     *  "desc": "成功",
     * }
     **/
    @RequestMapping(value = Routes.MERCHANT_CHANNEL_PRODUCTS_UPDATE, method = RequestMethod.POST)
    public JsonResult updateChannelProducts(HttpServletRequest request, @RequestBody ChannelDto channelDto) {
        UserInfoDto userInfoDto = userHelper.getSession(request);
        RestDoing doing = jsonResult -> {
            if (channelDto.getId() == null) {
                jsonResult.remind("id 不能为空", log);
                return;
            }
            if (channelDto.getProductIds() == null || channelDto.getProductIds().isEmpty()) {
                jsonResult.remind("所选产品不能为空", log);
                return;
            } else {
                for (Iterator<Long> itr = channelDto.getProductIds().iterator(); itr.hasNext(); ) {
                    Long newProductId = itr.next();
                    Product product = merchantProductRepository.findByIdAndMerchantIdAndMallId(newProductId, userInfoDto.merchant.getId(), userInfoDto.mall.getId());
                    if (product != null) {
                        ChannelProduct channelProduct = new ChannelProduct();
                        channelProduct.setChannelId(channelDto.getId());
                        channelProduct.setProductId(product.getId());
                        channelProduct.setProductName(product.getName());
                        channelProductRepository.save(channelProduct);
                    }
                }
            }
        };
        return doing.go(request, log);
    }


    /**
     *
     * @api {post} /merchant/channel/product/delete B端 渠道管理 产品删除
     * @apiGroup merchant_channel
     * @apiVersion 1.0.0
     * @apiHeader {String} userToken 用户token
     * @apiHeader {String} domain    请求域名
     * @apiParam {Long} id <code>必传参数</code>   渠道ID
     *@apiParam {List} productIds <code>必传参数</code>   选定产品ID集合
     * @apiSuccessExample {json} Success-Response:
     * {
     *  "code": "1",
     *  "desc": "成功",
     * }
     **/
    @RequestMapping(value = Routes.MERCHANT_CHANNEL_PRODUCTS_DELETE, method = RequestMethod.POST)
    public JsonResult deleteChannelProducts(HttpServletRequest request, @RequestBody ChannelDto channelDto) {
        UserInfoDto userInfoDto = userHelper.getSession(request);
        RestDoing doing = jsonResult -> {
            if (channelDto.getId() == null) {
                jsonResult.remind("id 不能为空", log);
                return;
            }
            if (channelDto.getProductIds() == null || channelDto.getProductIds().isEmpty()) {
                jsonResult.remind("所选产品不能为空", log);
                return;
            }

            for (Long productId : channelDto.getProductIds()) {
                ChannelProduct channelProduct = channelProductRepository.findByProductIdAndChannelIdAndIsDelete(productId, channelDto.getId(), Whether.NO);
                if (channelProduct != null) {
                    channelProduct.setIsDelete(Whether.YES);
                    channelProductRepository.save(channelProduct);
                }
            }

        };
        return doing.go(request, log);
    }

    /**
     *
     * @api {put} /merchant/channel/send/out B端 渠道管理 推广
     * @apiGroup merchant_channel
     * @apiVersion 1.0.0
     * @apiHeader {String} userToken 用户token
     * @apiHeader {String} domain    请求域名
     * @apiParam {Long} id <code>必传参数</code>   渠道ID
     * @apiSuccessExample {json} Success-Response:
     *{
     *"code": "1",
     *"desc": "成功",
     *"data": {
     *   "promoteUrl": "http://uploads.rockcent.com/dev/coupon/promote/201611/8144438785f0d66d37-682d-424f-a9c2-5bf3c270d4c7giftPacketPromote.jpg",
     *   "sendOutUrl": "http://beta.c.dev.rockcent.com/mall.php?method=detail&couponId=133&salesCode=B@AfvahtT"
     *  }
     *}
     **/
    @RequestMapping(value = Routes.MERCHANT_CHANNEL_SEND_OUT, method = RequestMethod.PUT)
    public JsonResult sendOutChannel(@RequestBody MerchantCouponDto dto, HttpServletRequest request) {

        UserInfoDto userInfoDto = userHelper.getSession(request);
        RestDoing doing = jsonResult -> {

            if (dto.getId() == null) {
                jsonResult.remind("渠道ID 不能为空", log);
                return;
            }
            Mall mall = mallRepository.findOne(userInfoDto.mall.getId());
            if (mall == null) {
                jsonResult.remind("平台不存在,请联系开发人员",log);
                return;
            }
            Merchant merchant = merchantRepository.findOne(userInfoDto.merchant.getId());
            String host = mall.getCustomerClientDomain();
            if (StringUtils.isBlank(host)) {
                host = mall.getMobileHostName();
            }
            Channel channel = merchantChannelRepository.getChannelByIdAndMerchantIdAndMallIdAndIsDelete(dto.getId(), userInfoDto.merchant.getId(), userInfoDto.mall.getId(), Whether.NO);

            StringBuffer url = new StringBuffer();
            //推广链接，待定
            http:
//beta.c.uat.rockcent.com/wechat_new/#/wechat/channelInfo/7
            url.append("http://").append(host)
                    .append("/wechat/channelInfo/").append(channel.getId()).append("/?id=").append(channel.getId());

            QrCodeDto qrCodeDto = new QrCodeDto();
            qrCodeDto.setId(userInfoDto.getId());
            qrCodeDto.setMallId(userInfoDto.mall.getId());
            qrCodeDto.setMerchantId(userInfoDto.merchant.getId());
            UploadImageFileDto uploadImageFileDto = null;
            Whether appFlag = channel.getAppFlag();
            ChannelClientType channelClientType = channel.getChannelClientType();
            if((appFlag!=null && appFlag==Whether.YES) || (channelClientType!=null && channelClientType==ChannelClientType.WXAPP)){
                MiniAppConfig miniAppConfig = miniAppConfigRepository.findByMallId(userInfoDto.mall.getId());
                if (miniAppConfig == null) {
                    jsonResult.remind("小程序配置信息不存在", log);
                    return;
                }
                uploadImageFileDto = qrCodeHelper.updateQRCodeForSmallProgram(channel.getId(),qrCodeDto, url.toString(), "channelSendOutQR.jpg", UploadFileBusinessType.MERCHANT_CHANNEL_PROMOTE, prop.env, prop.aliyunOssBucketName, prop.domainUploadsHttp,miniAppConfig);
            }else{
                uploadImageFileDto = qrCodeHelper.createQRCode(qrCodeDto, url.toString(), "channelSendOutQR.jpg", UploadFileBusinessType.MERCHANT_CHANNEL_PROMOTE, prop.env, prop.aliyunOssBucketName, prop.domainUploadsHttp);
            }


            channel.setPromoteUrl(uploadImageFileDto.getPath());
            merchantChannelRepository.save(channel);
            ChannelDto channelDto = new ChannelDto();
            channelDto.setSendOutUrl(url.toString());
            channelDto.setPromoteUrl(channel.getPromoteUrl());
            jsonResult.data = channelDto;
        };
        return doing.go(request, log);
    }

    /**
     * @api {get} /merchant/channel/product/order B端 查看渠道订单产品列表
     * @apiGroup merchant_channel
     * @apiVersion 1.0.0
     * @apiHeader {String} userToken 用户token
     * @apiHeader {String} domain    请求域名
     *
     * @apiParam {Long} channelId <code>必传参数</code> 渠道ID
     * @apiParam {String} productName 产品名称
     * @apiParam {String} dateSearchType YESTERDAY("昨天"), WEEK("最近一周"), MONTH("最近一个月"), QUATER("最近三个月"), 默认选中最近一个月
     * @apiParam {String} dateStart 开始时间
     * @apiParam {String} dateEnd 结束时间
     *
     * @apiSuccess {String} orderNum 订单编号
     * @apiSuccess {Long} productId 产品编号
     * @apiSuccess {String} productName 产品名称
     * @apiSuccess {Integer} saleCount 成交产品数
     * @apiSuccess {BigDecimal} paymentAmount 实付金额
     * @apiSuccess {Date} dateCreated 下单时间
     * @apiSuccess {Date} dateSettle 结算时间
     * @apiSuccess {String} status 订单状态 WAIT_PAYING(\"待支付\"),CANCEL(\"取消\"),PAYED(\"已支付\"),WAIT_SHIPPED(\"等待发货\"),SHIPPED(\"已发货\"),SHOP_PICKUP(\"到店自提\"),WAIT_STOCK(\"待备货\"),WAIT_SHOP_PICKUP(\"待到店自提\"),CONFIRM(\"已确认\"),WAIT_USE(\"待使用\"),PART_USE(\"部分使用\"),USED(\"已使用\"),FINISHED(\"已完成\"),APPLY_REJECT(\"申请退货\"),FINISHED_REJECT(\"已完成退货\"),APPLY_REFUND(\"申请退款\"),FINISHED_REFUND(\"已完成退款\")
     * @apiSuccess {String} orderType 订单类型 GOODS("实物商品"), SERVICE("到店服务")
     * @apiSuccess {String} productShoppingType 物流种类 SHOP_PICKUP("到店自提"), SHIPPING("物流")
     * @apiSuccess {String} sourceType SELF("自营下单"), MARKET("分销下单")
     * @apiSuccess {String} merchantRole 商家角色 当订单为分销订单时,用于区分供应商或者分销商 SELF("默认"),SUPPLIER("供应商"), DISTRIBUTOR("分销商")
     *
     * @apiSuccessExample {json} Success-Response:
     * {
     *   "code": "1",
     *   "desc": "成功",
     *   "data": {
     *     "data": [
     *       {
     *         "dateCreated": "2017-01-12 18:03:22",
     *         "productId": 1465,
     *         "productName": "商品+物流2哇",
     *         "saleCount": 2,
     *         "orderNum": "05131484215402166_7",
     *         "paymentAmount": 148.88,
     *         "dateSettle": "2017-01-12 18:59:11",
     *         "status": "FINISHED",
     *         "orderType": "GOODS",
     *         "productShoppingType": "SHOP_PICKUP",
     *         "sourceType": "MARKET",
     *         "merchantRole": "SUPPLIER"
     *       }
     *     ],
     *     "totalCount": 1,
     *     "totalPage": 1,
     *     "pageNo": 0,
     *     "pageSize": 10
     *   }
     * }
     **/
    @RequestMapping(value = Routes.MERCHANT_CHANNEL_PRODUCTS_ORDER, method = RequestMethod.GET)
    public JsonResult merchantChannelProductOrder(HttpServletRequest request, ChannelProductDto channelProductDto) {
        UserInfoDto userInfoDto = userHelper.getSession(request);
        RestDoing doing = jsonResult -> {
            if (channelProductDto.getChannelId() == null) {
                jsonResult.remind("channelId 不能为空", log);
                return;
            }
            String dateSearchType = channelProductDto.getDateSearchType();
            String dateStart = channelProductDto.getDateStart();
            String dateEnd = channelProductDto.getDateEnd();
            boolean isCheckType = true;
            boolean isCheckDate = true;
            if (StringUtils.isEmpty(dateSearchType)) {
                isCheckType = false;
            }
            if (StringUtils.isEmpty(dateStart) || StringUtils.isEmpty(dateEnd)) {
                isCheckDate = false;
            }
            if (!isCheckType && !isCheckDate) {
                jsonResult.remind("查询时间不能为空",log);
                return;
            }
            if (StringUtils.isNotBlank(dateSearchType) && !EnumUtils.isValidEnum(StatististicsType.class, dateSearchType)) {
                jsonResult.remind("searchDateType 必须为 YESTERDAY(\"昨天\"), WEEK(\"最近一周\"), MONTH(\"最近一个月\"), QUATER(\"最近三个月\")",log);
                return;
            }
            if (StringUtils.isNotEmpty(dateSearchType)) {
                Date today = DateUtils.getCurrentDate(DateFormatUtils.DATE_FORMAT1);
                //昨天
                if (StatististicsType.YESTERDAY == StatististicsType.valueOf(dateSearchType)) {
                    dateStart = DateUtils.addDayToDate(-1, today, DateFormatUtils.DATE_FORMAT1);
                    dateEnd = DateUtils.addDayToDate(-1, today, DateFormatUtils.DATE_FORMAT1);
                }
                //每周
                if (StatististicsType.WEEK == StatististicsType.valueOf(dateSearchType)) {
                    dateStart = DateUtils.addDayToDate(-6, today, DateFormatUtils.DATE_FORMAT1);
                    dateEnd = DateUtils.getCurrentTime(DateFormatUtils.DATE_FORMAT1);
                }
                //近一个月
                if (StatististicsType.MONTH == StatististicsType.valueOf(dateSearchType)) {
                    dateStart = DateUtils.addMothToDate(-1, today, DateFormatUtils.DATE_FORMAT1);
                    dateEnd = DateUtils.getCurrentTime(DateFormatUtils.DATE_FORMAT1);
                }
                //近三个月
                if (StatististicsType.QUATER == StatististicsType.valueOf(dateSearchType)) {
                    dateStart = DateUtils.addMothToDate(-3, today, DateFormatUtils.DATE_FORMAT1);
                    dateEnd = DateUtils.getCurrentTime(DateFormatUtils.DATE_FORMAT1);
                }
            }
            if (StringUtils.isNotEmpty(dateStart)) {
                channelProductDto.setDateStart(dateStart + " 00:00:00");
            }
            if (StringUtils.isNotEmpty(dateEnd)) {
                channelProductDto.setDateEnd(dateEnd + " 23:59:59");
            }
            channelProductDto.setMerchantId(userInfoDto.merchant.getId());
            channelProductDto.setMallId(userInfoDto.mall.getId());
            PageResult pageResult = this.getPage(channelProductDto.getPageNo(), channelProductDto.getPageSize());
            PageResult<ChannelProductDto> result = merchantOrderRepository.findProductOrdersByProductNameAndChannelIdAndDate(channelProductDto, pageResult);
            jsonResult.data = result;
        };
        return doing.go(request, log);
    }
}
